package leetcode.lcp.lcp20220924;

import java.awt.Point;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

//Solution3Test
public class Solution32 {

	int[] x = new int[] { 0, -1, 0, 1 };// -1 右转
	int[] y = new int[] { 1, 0, -1, 0 };// +1 左转
	char[][] arr;
	int m, n;
	Set<Point> ans;
	Map<Integer, Set<Point>> been;

	public int[][] ballGame(int num, String[] plate) {
		m = plate.length;
		n = plate[0].length();
		arr = new char[m][n];
		for (int i = 0; i < m; i++) {
			arr[i] = plate[i].toCharArray();
		}
		ans = new HashSet<>();
		been = new HashMap<>();
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				char cur = arr[i][j];
				if (cur == 'O') {
					this.f(i, j, num);
				}
			}
		}
		int len = ans.size();
		int[][] ret = new int[len][2];
		int w = 0;
		for (Point p : ans) {
			ret[w][0] = p.x;
			ret[w][1] = p.y;
			w++;
		}
		return ret;
	}

	public int index(int i, int j) {
		return i * n + j;
	}

	private void f(int i, int j, int num) {
		this.ff(i, j, num, 0);// 向右
		this.ff(i, j, num, 1);// 向上
		this.ff(i, j, num, 2);// 向左
		this.ff(i, j, num, 3);// 向下
	}

	private void ff(int i, int j, int num, int k) {
		if (i < 0 || i == m || j < 0 || j == n) {
			return;
		}
		int index = this.index(i, j);
		if (been.containsKey(index) && been.get(index).contains(new Point(num, k))) {
			return;
		}
		Set<Point> set = been.getOrDefault(index, new HashSet<>());
		set.add(new Point(num, k));
		been.put(index, set);
		if (arr[i][j] == 'W') {
			k = (k + 3) % 4;
		} else if (arr[i][j] == 'E') {
			k = (k + 1) % 4;
		}
		if (i == 0 && j != 0 && j != n - 1 && k == 1 && arr[i][j] == '.') {
			ans.add(new Point(i, j));
			return;
		} else if (i == m - 1 && j != 0 && j != n - 1 && k == 3 && arr[i][j] == '.') {
			ans.add(new Point(i, j));
			return;
		} else if (j == 0 && i != 0 && i != m - 1 && k == 2 && arr[i][j] == '.') {
			ans.add(new Point(i, j));
			return;
		} else if (j == n - 1 && i != 0 && i != m - 1 && k == 0 && arr[i][j] == '.') {
			ans.add(new Point(i, j));
			return;
		}
		if (num == 0) {// 最后的位置
			return;
		}
		int numnext = num - 1;
		int nexti = i + x[k], nextj = j + y[k];
		this.ff(nexti, nextj, numnext, k);
	}

}
